Controlling Output
Let's switch topics for a moment. Thus far, we have been merely displaying
data using the print
statement and its default characteristics =
namely, printing a space between components and ending the statement with a line
break. We can control this behavior.
Item Separator
We have seen that you can print multiple literal constants and variables
using the print
statement:
Code | Output |
---|---|
print("A", "B", "C") |
A B C |
color = "blue" |
The sky is blue |
Python automatically separates each component using a space. By what if we don't want to use a space? What if we want to use a hyphen or a comma or nothing at all? Python has you covered.
The components which make up the print statement are called
arguments. In the above examples, the string "I see"
, the
variable number
, the variable animal
, and the string
"running"
are all arguments.
The print statement has a special argument which controls item separator:
Code | Output | Notes |
---|---|---|
print("A", "B", "C", sep="") |
ABC |
We set the |
color = "blue" |
The sky isblue |
We set the |
You can use any string value for the sep argument:
Code | Output | Notes |
---|---|---|
print("A", "B", "C", sep="-") |
A-B-C |
We set the |
print("A", "B", "C", sep="!!") |
A!!B!!C |
We set the |
print("A", "B", "C", sep="\n") |
A |
We set the |
When you do not specify the sep
argument, Python defaults to a
space. When you want to use it, just separate it from the other components with
a comma, then set your separator to whatever string you like.
End Behavior
We have also seen that the print
statement automatically ends
each statement with a line break.
Code | Output |
---|---|
print("Line 1") |
Line 1 |
print("Line 1\nLine 2") |
Line 1 |
The print statement also has an argument to control the end behavior:
Code | Output | Notes |
---|---|---|
print("Line 1", end=" ") |
Line 1 Line 2 |
We set the |
print("Line 1", end="") |
Line 1Line 2 |
We set the |
You can use any string for the end
argument as well:
Code | Output | Notes |
---|---|---|
print("Line 1", end="\n\n") |
Line 1 |
Two line breaks |
print("Line 1", end="\n\t~") |
Line 1 |
Line break, tab, and a tilde |
When you do not specify the end
argument, Python defaults to a
line break. When you want to use it, just separate it from the other components
with a comma, then set your end
argument to whatever string you
like.
Using Them Together
You can use the sep
and end
arguments individually
as needed or together. The order does not matter, so long as they follow your
list of components. Here are some examples:
Code | Output |
---|---|
print("Line 1", "Line 2", sep="!", end="") |
Line 1!Line 2Line3 |
print("Line 1", "Line 2", end=" ", sep="\n") |
Line 1 |
Formatting Numbers
We saw in the last lesson that numbers do not always display "prettily" when we want them to. For example, if we were to calculate the 4.75% tax on a $2.99 purchase we get:
Code | Output |
---|---|
tax_rate = 0.0475 |
You pay 0.142025 in tax |
Wait a minute! We can't pay $0.142025 in tax – we have no coin to represent
fractions of a penny! It would make sense to round down to 0.14 and just display
that. Fortunately, Python makes it easy for us to format numbers using the
format
function.
Just like the print
statement, the format
function
accepts arguments. At the very least, it requires two: the number being
formatted, and the format specifier. The format specifier is a special
string which instructs Python on how to present the value. It is actually a
whole language unto itself, but we'll display some of the more common
examples.
Formatting Floats
Code | Output |
---|---|
tax_rate = 0.0475 |
You pay 0.14 in tax |
The code we used - format(tax, ".2f")
– accepted the variable
tax as the first argument. The second argument is the format specifier. The
.2
represents the precision we want; in this case, 2 decimal
places. The f
represents the type of formatting we are performing.
There is a whole library on the different types, but in this case f is for a
fixed point number.
Note that format()
will round up or down depending on the value
of the next decimal place. If the number is greater than or equal to 5, it will
round up. If the decimal is less than 5, it will round down.
Let's look at an estimation of the number pi and format it.
Code | Result | Notes |
---|---|---|
pi = 3.14159265359 |
none |
We assign the approximate value of pi to the variable
|
format(pi, ".0f") |
3 |
|
format(pi, ".1f") |
3.1 |
|
format(pi, ".2f") |
3.14 |
|
format(pi, ".3f") |
3.142 |
|
format(pi, ".4f") |
3.1416 |
|
When you are dealing with large numbers, you might want to use a comma to separate the thousandths place like this: 14,726,986.19. We just need to add a comma to the format specifier:
Code | Result |
---|---|
big_number = 14726986.192271 |
none |
format(big_number, ",.0f") |
14,726,986 |
format(big_number, ",.1f") |
14,726,986.2 |
format(big_number, ",.2f") |
14,726,986.19 |
Perhaps we want to format a percentage? In this case, we drop the
f
from the format specifier and replace it with a percentage sign
%
. Then we set our precision level to whatever we like:
Code | Result |
---|---|
test_score = 0.754931 |
none |
format(test_score, ".0%") |
75% |
format(test_score, ".1%") |
75.5% |
format(test_score, ".2%") |
75.49% |
You can even combine the comma formatting with the percentage:
Code | Result |
---|---|
sales_increase = 74290.754931 |
none |
format(sales_increase, ",.2%") |
7,429,075.49% |
Formatting Integers
Integers don't have decimal values as they are whole numbers. You can still
use ,.0f
to format a large integer, but it would be more proper to
use d
(for "decimal integer in base 10") instead of f
.
And since integers do not have decimal values, we can drop the precision. Look
how these two different format specifiers produce identical results.
Code | Result |
---|---|
cars = 10473 |
none |
format(cars, ",.0f") |
10,473 |
format(cars, ",d") |
10,473 |
Debugging
When a syntax or runtime error occurs, the error message contains a lot of information, but it can be overwhelming. The most useful parts are usually:
- What kind of error it was, and
- Where it occurred.
Syntax errors are usually easy to find, but there are a few gotchas. Whitespace errors can be tricky because spaces and tabs are invisible and we are used to ignoring them.
>>> x = 5 >>> y = 6 File "<stdin>", line 1 y = 6 ^ IndentationError: unexpected indent
In this example, the problem is that the second line is indented by one
space. But the error message points to y
, which is misleading. In
general, error messages indicate where the problem was discovered, but the
actual error might be earlier in the code, sometimes on a previous line.
The same is true of runtime errors. Suppose you are trying to compute a signal-to-noise ratio in decibels. The formula is SNRdb = 10 log10 (Psignal / Pnoise). In Python, you might write something like this:
import math signal_power = 9 noise_power = 10 ratio = signal_power // noise_power decibels = 10 * math.log10(ratio) print(decibels)
When you run this program, you get an exception:
Traceback (most recent call last): File "snr.py", line 5, in ? decibels = 10 * math.log10(ratio) ValueError: math domain error
The error message indicates line 5, but there is nothing wrong with that
line. To find the real error, it might be useful to print the value of
ratio
, which turns out to be 0. The problem is in line 4, which
uses floor division //
instead of floating-point division
/
.
You should take the time to read error messages carefully, but don’t assume that everything they say is correct.